﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;

namespace Cinser.DataTranslate.TaskManager
{
    /// <summary>
    /// 带消息的委托
    /// </summary>
    /// <param name="msg"></param>
    public delegate void MsgHandler(Cinser.Common.Model.Message msg);
    /// <summary>
    /// 任务操作类型
    /// </summary>
    public enum TaskOperation
    {
        /// <summary>
        /// 开始
        /// </summary>
        Begin,
        /// <summary>
        /// 停止
        /// </summary>
        Stop,
        /// <summary>
        /// 继续
        /// </summary>
        Continue,
        /// <summary>
        /// 重新开始
        /// </summary>
        DoRepeat,
        /// <summary>
        /// 修复任务：重新执行上次任务带异常的子任务
        /// </summary>
        Repair
    }
    /// <summary>
    /// 任务基类
    /// </summary>
    public abstract class TaskBase : INotifyPropertyChanged, INotifyPropertyChanging
    {
        string taskName, id, subtitle, introduce, logId;       
        DateTime beginDate, finishDate;
        List<Cinser.Common.Model.Message> taskMsg;
        int totalTaskCount, finishedTotalTaskCount, subTaskCount, finishedSubTaskCount, errorNum;
        double subTaskFinishPercent, totalTaskFinishPercent;

        /// <summary>
        /// 属性改变后执行的事件
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 属性改变中执行的事件
        /// </summary>
        public event PropertyChangingEventHandler PropertyChanging;
        /// <summary>
        /// 任务完成时执行的事件
        /// </summary>
        public event EventHandler TaskComplate;
        /// <summary>
        /// 当添加了新任务消息时触发的委托
        /// </summary>
        public MsgHandler MessageAdded;
        
        /// <summary>
        /// 日志路径
        /// </summary>
        public string LogPath
        {
            //get
            //{
            //    return string.Format("{0}\\{1}.txt", Common.AppUtility.LogFolderPath, LogId);
            //}
            get;set;
        }
        /// <summary>
        /// 日志ID
        /// </summary>
        public string LogId
        {
            get
            {
                if (string.IsNullOrEmpty(logId) == false)
                    return logId;
                else
                {
                    logId = string.Format("{0}_{1}_{2}", BeginDate.ToString("yyyyMMddhhmmss"), TaskName, this.Id);
                    return logId;
                }
            }
            set
            {
                logId = value;
            }
        }
        /// <summary>
        /// 总任务数
        /// </summary>
        public int TotalTaskCount
        {
            get { return totalTaskCount; }
            set { totalTaskCount = value; }
        }
        /// <summary>
        /// 已完成总任务数
        /// </summary>
        public int FinishedTotalTaskCount
        {
            get { return finishedTotalTaskCount; }
            set { finishedTotalTaskCount = value; }
        }
        /// <summary>
        /// 总任务完成百分比
        /// </summary>
        public double TotalTaskFinishPercent
        {
            get { return totalTaskFinishPercent; }
            set { totalTaskFinishPercent = value; }
        }

        /// <summary>
        /// 当前子任务完成百分比
        /// </summary>
        public double SubTaskFinishPercent
        {
            get { return subTaskFinishPercent; }
            protected set
            {
                SetValue("SubTaskFinishPercent", value, ref subTaskFinishPercent);
            }
        }
        /// <summary>
        /// 子任务完成数
        /// </summary>
        public int FinishedSubTaskCount
        {
            get { return finishedSubTaskCount; }
            set
            {
                finishedSubTaskCount = value;
                SubTaskFinishPercent = ((double)FinishedSubTaskCount / (double)SubTaskCount) * 100f;
            }
        }
        /// <summary>
        /// 子任务总数
        /// </summary>
        public int SubTaskCount
        {
            get { return subTaskCount; }
            set { subTaskCount = value; }
        }

        /// <summary>
        /// 任务执行过程出错子任务数
        /// </summary>
        public int ErrorNum
        {
            get { return errorNum; }
            set { errorNum = value; }
        }
        /// <summary>
        /// 任务介绍
        /// </summary>
        public string Introduce
        {
            get { return introduce; }
            set
            {
                SetValue("Introduce", value, ref introduce);
            }
        }
        /// <summary>
        /// 触发任务完成事件
        /// </summary>
        protected void FireTaskComplate()
        {
            if (TaskComplate != null)
                TaskComplate(this, null);
        }
        /// <summary>
        /// 任务子标题
        /// </summary>
        public string Subtitle
        {
            get { return subtitle; }
            set
            {
                SetValue("Subtitle", value, ref subtitle);
            }
        }
        /// <summary>
        /// 完成时间
        /// </summary>
        public DateTime FinishDate
        {
            get
            {
                if (finishDate == null)
                    finishDate = DateTime.Now;
                return finishDate;
            }
            set { finishDate = value; }
        }
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime BeginDate
        {
            get
            {
                if (beginDate == null)
                    beginDate = DateTime.Now;
                return beginDate;
            }
            set { beginDate = value; }
        }        
        /// <summary>
        /// 任务消息
        /// </summary>
        protected List<Cinser.Common.Model.Message> TaskMsg
        {
            get
            {
                if (taskMsg == null)
                {
                    taskMsg = new List<Cinser.Common.Model.Message>();
                }
                return taskMsg;
            }
            set { taskMsg = value; }
        }        
        /// <summary>
        /// 任务ID
        /// </summary>
        public string Id
        {
            get {
                if (string.IsNullOrEmpty(id))
                    id = Guid.NewGuid().ToString();
                return id; 
            }
            set { id = value; }
        }
        /// <summary>
        /// 任务名称
        /// </summary>
        public string TaskName
        {
            get { return taskName; }
            set { taskName = value; }
        }
        /// <summary>
        /// 执行任务
        /// </summary>
        public abstract void Execute();
        /// <summary>
        /// 修复任务
        /// </summary>
        public abstract void Repair();
        /// <summary>
        /// 保存任务
        /// </summary>
        public abstract void Save();
        /// <summary>
        /// 停止
        /// </summary>
        public abstract void Stop();
        /// <summary>
        /// 继续
        /// </summary>
        public abstract void Continue();
        /// <summary>
        /// 根据ID读取任务
        /// </summary>
        public abstract TaskBase Read(string id);
        /// <summary>
        /// 重置任务参数
        /// </summary>
        public virtual void Reset()
        {
            this.TotalTaskCount = 0;
            this.TotalTaskFinishPercent = 0;
            this.ErrorNum = 0;
            this.FinishedTotalTaskCount = 0;            
        }
        /// <summary>
        /// 添加一条任务消息
        /// </summary>
        /// <param name="msg"></param>
        public virtual void AddTaskMsg(Cinser.Common.Model.Message msg)
        {
            this.TaskMsg.Add(msg);
            if (MessageAdded != null)
                MessageAdded(msg);
        }
        /// <summary>
        /// 写入任务日志
        /// </summary>
        /// <param name="logStr"></param>
        protected virtual void WriteLog(string logStr)
        {
            if (File.Exists(this.LogPath) == false)
            {
                File.Create(LogPath).Close();
                File.WriteAllText(LogPath, logStr);
            }
            else
            {
                StreamWriter sw = File.AppendText(LogPath);
                sw.WriteLine(logStr);
                sw.Close();
            }
        }
        /// <summary>
        /// 写入数据库操作日志
        /// </summary>
        /// <param name="logStr">日志描述</param>
        /// <param name="tbName">表名称</param>
        /// <param name="sqlWhere">数据条件</param>
        public virtual void WriteDbLog(string logStr, string tbName, string sqlWhere = "1=1")
        {
            //2014/8/13 12:01:22:程序启动.[data:tableName&id='1' and type='2']
            logStr = string.Format("{0}:{1}.[data:{2}&{3}]\n", DateTime.Now.ToString(), logStr, tbName, sqlWhere);
            WriteLog(logStr);
        }
        /// <summary>
        /// 写入文件操作日志
        /// </summary>
        /// <param name="logStr">消息名称</param>
        /// <param name="filePath">文件路径</param>
        public virtual void WriteFileLog(string logStr, string filePath)
        {
            //2014/8/13 12:01:22:程序启动.[file:K:\win32_11gR2_client.rar]
            logStr = string.Format("{0}:{1}.[file:{2}]\n", DateTime.Now.ToString(), logStr, filePath);
            WriteLog(logStr);
        }
        /// <summary>
        /// 设置属性
        /// </summary>
        protected virtual bool SetValue<TValueType>(string propertyName, TValueType newValue, ref TValueType oldValue)
        {
            bool isChanged = (!Object.Equals(newValue, oldValue));
            if (isChanged)
            {
                OnPropertyChanging(propertyName);
                oldValue = newValue;
                OnPropertyChanged(propertyName);
            }
            return isChanged;

        }        
        /// <summary>
        /// 出发属性改变中事件
        /// </summary>
        /// <param name="propertyName"></param>
        protected virtual void OnPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }
        /// <summary>
        /// 触发属性改变完成事件
        /// </summary>
        /// <param name="propertyName"></param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
